package com.tencent.wxcloudrun.filter;

import com.alibaba.fastjson2.JSON;
import com.tencent.wxcloudrun.common.Utils;
import com.tencent.wxcloudrun.common.ThreadLocalUtils;
import com.tencent.wxcloudrun.model.AdminUser;
import com.tencent.wxcloudrun.response.ErrorCodeMsgEnum;
import com.tencent.wxcloudrun.response.R;
import com.tencent.wxcloudrun.service.AdminUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * ClassName: MyFilter
 * Package: com.tencent.wxcloudrun.MyFilter
 * Description:
 *
 * @Date: 2023/1/23 6:41 PM
 * @Author: wht
 */
@Order(1)
@Slf4j
@WebFilter(filterName = "MyFilter", urlPatterns = {"/*"})
public class MyFilter implements Filter {


    @Autowired
    AdminUserService adminUserService;

    //路径匹配器，支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("----FilterDemo01过滤器初始化----");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        ThreadLocalUtils.setTime();

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        response.setHeader("Content-Type", "application/json; charset=utf-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, PATCH, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");


        //获取本次请求的URI
        String requestURI = request.getRequestURI();
        log.info("请求路径：" + requestURI);

        //判断本次请求是否需要处理。如果不需要处理，则直接放行
        String[] urls = new String[]{"/admin/login", "/websocket/*"};
        if (check(urls, requestURI)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

//        判断token是否正确
        String token = request.getHeader("Authorization");
        if (token == null) {
            response.getWriter().write(JSON.toJSONString(R.error(ErrorCodeMsgEnum.TOKEN_ERROR)));
            return;
        }
        AdminUser adminUser = adminUserService.getOneAdminUserByToken(token);
        if (adminUser == null) {
            response.getWriter().write(JSON.toJSONString(R.error(ErrorCodeMsgEnum.TOKEN_ERROR)));
            return;
        }
        int i = token.indexOf("0.");
        Long time = Long.parseLong(token.substring(0, i));
        Long now_time = ThreadLocalUtils.getTime();
//        System.out.println(now_time);
//        System.out.println(time);
        if (now_time - time > 3600000) {
//                token过期
            response.getWriter().write(JSON.toJSONString(R.error(ErrorCodeMsgEnum.TOKEN_ERROR)));
            return;
        }

        if (now_time - time > 1800000) {
//        if (now_time - time > 1800000) {
//            log.info("------------ajsdkfjlka");
//              token快过期了，重新生成
            String new_token = Utils.getNewToken();

//            更新数据库里的token
            AdminUser user = new AdminUser();
            user.setId(adminUser.getId());
            user.setToken(new_token);

            adminUserService.updateOneAdminUserById(user);

//            更新用户的token
//            System.out.println(new_token + "++++++++++++");
            adminUser.setToken(new_token);
//            System.out.println(adminUser);
        }
//        System.out.println("++++++++++++");
//        System.out.println(ThreadLocalUtils.getUser());
        ThreadLocalUtils.setUser(adminUser);
//        System.out.println(ThreadLocalUtils.getUser());
        filterChain.doFilter(servletRequest, servletResponse);

//        AdminUser adminUser = ThreadLocalUtils.getUser();

//        if (adminUser == null) {
//            log.info("----------3");
//            // 没有用户信息
//            response.getWriter().write(JSON.toJSONString(R.error(ErrorCodeMsgEnum.TOKEN_ERROR)));
//            return;
//        }
//        String token = adminUser.getToken();
//        String token = request.getHeader("Authorization");
//        log.info(token);
//        log.info(token);
//        if (token.equals(token)) {
//            String[] strings = token.split("\\.");
//
//            Long time = Long.parseLong(strings[0]);
//            Long now_time = System.currentTimeMillis();
//            if (now_time - time > 3600000) {
////                token过期
//                response.getWriter().write(JSON.toJSONString(R.error(ErrorCodeMsgEnum.TOKEN_ERROR)));
//                return;
//            } else if (now_time - time > 1800000) {
////              token快过期了，重新生成
//                String new_token = Utils.getNewToken();
//                adminUser.setToken(new_token);
//                ThreadLocalUtils.setUser(adminUser);
//                filterChain.doFilter(servletRequest, servletResponse);
//                return;
//            }
//        } else {
//            //如果token不相等，通过输出流方式向客户端页面响应数据
//            response.getWriter().write(JSON.toJSONString(R.error(ErrorCodeMsgEnum.TOKEN_ERROR)));
//            return;
//        }
    }

    @Override
    public void destroy() {
//        log.info("info:---------------------------------end:" + (System.currentTimeMillis() - ThreadLocalUtils.getTime()));
//        ThreadLocalUtils.remove();
    }

    /**
     * 路径匹配，检查本次请求是否需要放行
     *
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls, String requestURI) {
        for (String url : urls) {
            if (PATH_MATCHER.match(url, requestURI)) {
                return true;
            }
        }
        return false;
    }
}
